home *** CD-ROM | disk | FTP | other *** search
- /*
-
- This is the source code of the TCP/IP Support stuff
- of rtgmaster.library... originally it was included,
- as in rtgmaster.library V5 TCP/IP Support had to
- contain a LOT of Forbid()/Permit() calls, that slowed
- the thing down. (This was only needed for AmiTCP stuff
- inside a Shared Library). In the meanwhile, i got
- a reply from the coders of AmiTCP how to do this
- inside a shared library without a single Forbid()/Permit()
- call... so you could call this source obsolete...
- if you want to know how TCP/IP works NATIVE, you
- still can have a look at it :) Of course this source
- is only usable from C, while the rtgmaster stuff is
- usable from ASM, too... i hope i did not forget
- any includes for the source version...
-
- THIS STUFF IS OBSOLETE, AS THE PROBLEMS THAT I HAD
- WITH TCP/IP SUPPORT AT THE BEGINNING, DISAPPEARED...
- IT IS THE CODE OF rtgmaster.library V6, AND DOES
- NOT SUPPORT UDP, CONTRARY TO rtgmaster.library V7 !!!
-
- */
-
-
- // NOTE : Function Parameters are nearly the same, only
- // that you have to provide a struct Library *SocketBase,
- // and have to call SocketBase=OpenLibrary("bsdsocket.library",4);
- // instead of providing SocketBase as parameters...
-
- // Urgent note : If you want to use this code from different
- // TASKS, provide the SocketBase as additional parameter "SBase" and
- // give each function a local variable
- // struct Library *SocketBase=SBase;
- // Else you will get a LOT of AmiTCP error messages (this is the
- // "famous" rtgmaster V6 speedfix. At the beginning i had a
- // Forbid();/* Global */ SocketBase=SBase;Permit(); which
- // of course is much slower than the local variable stuff...
-
- #include <sys/types.h>
- #include <exec/nodes.h>
- #include <clib/socket_protos.h>
- #include <pragmas/socket_pragmas.h>
- #include <clib/netlib_protos.h>
- #include <netinet/in.h>
- #include <netdb.h>
- #include <sys/ioctl.h>
- #include <rtgmaster/rtgTCPIP.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <clib/alib_protos.h>
- #include <exec/memory.h>
- #include <string.h>
- #include <ctype.h>
-
- // Note : Some of these includes might ACTUALLY
- // be not needed... i hope i forgot no include :)
-
- #define CREATE(result, type, number) do {\
- if (!((result) = (type *) calloc ((number), sizeof(type))))\
- result=0;} while(0);
-
- struct RTG_Socket *OpenServer(int port, int mode, int protocol)
- {
- int opt,s;
- long handle;
- struct sockaddr_in sa;
- static struct RTG_Socket rs;
- if ((s=socket(AF_INET,mode,protocol))<0) return(0);
- #if defined(SO_SNDBUF)
- opt = (LARGE_BUFSIZE + GARBAGE_SPACE);
- if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, (char *) &opt, sizeof(opt)) < 0) return(0);
- #endif
-
- #if defined(SO_REUSEADDR)
- opt = 1;
- if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *) &opt, sizeof(opt)) < 0) return(0);
- #endif
-
- #if defined(SO_LINGER)
- {
- struct linger ld;
-
- ld.l_onoff = 0;
- ld.l_linger = 0;
- if (setsockopt(s, SOL_SOCKET, SO_LINGER, (char *) &ld, sizeof(ld)) < 0) return(0);
- }
- #endif
-
- sa.sin_family = AF_INET;
- sa.sin_port = htons(port);
- sa.sin_addr.s_addr = htonl(INADDR_ANY);
- if (bind(s, (struct sockaddr *) &sa, sizeof(sa)) < 0)
- {
- CloseSocket(s);
- return(0);
- }
- listen(s,5);
- rs.s=s;
- rs.num=1;
- rs.list=0;
- FD_ZERO(&(rs.input_set));
- FD_ZERO(&(rs.output_set));
- FD_ZERO(&(rs.exc_set));
- return(&rs);
- }
-
- void makeservaddr(struct sockaddr_in *address, char *host, int port);
- void makeservaddr(struct sockaddr_in *address, char *host, int port)
- {
- struct hostent *hi;
- address->sin_family=AF_INET;
- hi=gethostbyname(host);
- bcopy(hi->h_addr,&address->sin_addr,hi->h_length);
- address->sin_port=port;
- }
-
- struct RTG_Socket *OpenClient(char *host, int port, int mode, int protocol)
- {
- struct sockaddr_in sa;
- struct sockaddr_in *sb;
- struct hostent *hi;
- long handle;
- static struct RTG_Socket rs;
- int s;
- if ((s=socket(AF_INET,mode,protocol))<0) return(0);
- makeservaddr(&sa,host,port);
- if (connect(s,&sa,sizeof(sa))<0) return(0);
- rs.s=s;
- rs.num=1;
- rs.list=0;
- return(&rs);
- }
-
- struct RTG_Socket *RunServer(struct RTG_Socket *s, struct RTG_Buff *in_buffer, struct RTG_Buff *out_buffer, int maxplayers)
- {
- int maxdesc;
- int num=0;
- struct timeval null_time;
- struct RTG_Socket *d;
- int socknum=0;
- struct RTG_Socket *new_conn=0;
- if (maxplayers>12) maxplayers=12;
- null_time.tv_sec=0;
- null_time.tv_usec=0;
- if (s->list==0)
- {
- FD_ZERO(&(s->input_set));
- FD_SET(s->s,&(s->input_set));
- if (WaitSelect((s->s)+1, &(s->input_set), (fd_set *) 0, (fd_set *) 0, NULL,0) >= 0)
- {
- // New connection...
- }
- }
- FD_ZERO(&(s->input_set));
- FD_ZERO(&(s->output_set));
- FD_ZERO(&(s->exc_set));
- FD_SET(s->s,&(s->input_set));
- maxdesc=s->s;
- if (s->list!=0) for (d=s->list;d;d=d->list)
- {
- if ((d->s)>maxdesc) maxdesc=d->s;
- FD_SET(d->s,&(s->input_set));
- FD_SET(d->s,&(s->output_set));
- FD_SET(d->s,&(s->exc_set));
- }
- if (WaitSelect(maxdesc+1,&(s->input_set),&(s->output_set),&(s->exc_set),&null_time,0) >= 0)
- {
- // We have input...
- }
- if (FD_ISSET(s->s,&(s->input_set)))
- {
- // Allocate new descriptor
- int i;
- struct sockaddr_in peer;
- int desc;
- if ((desc = accept(s->s, 0,0))==-1)
- {
- return(0);
- }
- else
- {
- for (d=s->list;d;d=d->list)
- socknum++;
- if (socknum>=maxplayers)
- {
- CloseSocket(desc);
- return(0);
- }
- if (s->list!=0) for(d=s->list;(d->list);d=d->list);
- else d=s;
- if (s->num==maxplayers) return(0);
- CREATE(d->list,struct RTG_Socket,1);
- if ((d->list)==0) return(0);
- d=d->list;
- d->s=desc;
- d->num=1;
- d->list=0;
- new_conn=d;
- s->num++;
- }
- }
- if (s->list!=0) for (d=s->list;d;d=d->list)
- {
- if (FD_ISSET(d->s,&(s->exc_set)))
- {
- FD_CLR(d->s,&(s->input_set));
- FD_CLR(d->s,&(s->output_set));
- CloseSocket(d->s);
- }
- }
- if (s->list!=0) for (d=s->list;d;d=d->list)
- {
- if (FD_ISSET(d->s,&(s->input_set)))
- {
-
- int state;
- state=recv(d->s,in_buffer->sock[num],in_buffer->in_size,0);
- in_buffer->num[num]=d->s;
- num++;
- if (state<0) {num--;CloseSocket(d->s);in_buffer->num[num]=-1;}
- //Handle input, if it fails, CloseSocket !!!
- }
- }
- if (s->list!=0) for (d=s->list;d;d=d->list)
- {
- if (FD_ISSET(d->s,&(s->output_set)))
- {
- int state,f,g;
- g=-1;
- for (f=0;((f<maxplayers)&&(g==-1));f++)
- if (out_buffer->num[f]==d->s) g=f;
- state=send(d->s,&(out_buffer->sock[g]),out_buffer->out_size,0);
- if (state<0) CloseSocket(d->s);
- // Handle output, if it fails, CloseSocket !!!
- }
- }
- return(new_conn);
- }
-
- void CloseServer(struct RTG_Socket *s)
- {
- if (s->s) CloseSocket(s->s);
- s->s=0;
- }
-
- void CloseClient(struct RTG_Socket *s)
- {
- if (s->s) CloseSocket(s->s);
- s->s=0;
- }
-
- int RtgSend(struct RTG_Socket *s, char *message, int len)
- {
-
- int test;
- test=(send(s->s,message,len,0));
- return(test);
- }
-
- int RtgRecv(struct RTG_Socket *s, char *message, int len)
- {
- int test;
- test=(recv(s->s,message,len,0));
- return(test);
- }
-
- struct RTG_Socket *RtgAccept(struct RTG_Socket *s)
- {
- static struct RTG_Socket rs;
- rs.s=accept(s->s,0,0);
- if (rs.s>=0)
- {
- rs.num=1;
- rs.list=0;
- return(&rs);
- }
- else return(0);
- }
-
- int RtgIoctl(struct RTG_Socket *s, long *arg)
- {
- int test;
- test=(IoctlSocket(s->s,FIONBIO,arg));
- return(test);
- }
-
-
-